import { Button, message } from "antd";
import { createContext, FC, ForwardRefExoticComponent, RefAttributes, MutableRefObject, useCallback, useEffect, useRef, useState, Fragment } from "react";
import { useSearchParams } from "react-router-dom";
import { updateSource } from "src/api";
import { ConfigurePageContentItem, ConfigurePageContentItemType, ConfigurePageContextProps, GoodsItem } from "./ConfigurePageType";
import PreviewDevice from "./PreviewDevice/PreviewDevice";
import SwiperEditor, { SwiperEditorRef } from "./EditorArea/SwiperEditor/SwiperEditor";
import { MiniAppPageRecord } from "../List/MiniAppPageType";
import { LeftOutlined } from "@ant-design/icons";
import { history } from "@/util/history";
import CatEditor from "./EditorArea/CatEditor/CatEditor";
import { StyledEditorArea } from "./ConfigurePage.styled";
import { MINIAPPPAGE } from "@/route";
import GoodsEditor from "./EditorArea/GoodsEditor/GoodsEditor";
import { cloneDeep } from "lodash";
import { getPageSetting } from "@/api/page";
import { toast } from "@/util";
import RichTextEditor from "./EditorArea/RichTextEditor/RichTextEditor";

export const ConfigurePageContext = createContext<ConfigurePageContextProps>({
	selectedIndex: 0,
	content: [],
	setSelectedIndex: () => null,
	setContent: () => null,
	addTypeOpen: false,
	setAddTypeOpen: () => null,
	operateIndex: 0,
	setOperateIndex: () => null,
});
const ConfigurePage = () => {
	const [searchParams] = useSearchParams();
	const fetchData = async () => {
		const id = searchParams.get("id");
		if (!id) return;
		const res = await getPageSetting(id);
		const data = res.data || [];
		try {
			setContent(data);
			initValues(data);
		} catch (err) {
			console.dir(err);
		}
	};
	const [content, setContent] = useState<ConfigurePageContentItem[]>([]);
	const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
	const [addTypeOpen, setAddTypeOpen] = useState(false);
	const swiperEditorRef = useRef<SwiperEditorRef | null>(null);
	const [submitLoading, setSubmitLoading] = useState(false);
	const updateContent = useCallback(async () => {
		const id = searchParams.get("id");
		if (!id) return;
		setSubmitLoading(true);
		try {
			const copiedContent = cloneDeep(content) as (ConfigurePageContentItem | { list: string[]; type: ConfigurePageContentItemType })[];
			copiedContent.forEach(item => {
				if (["verticalGoods", "horizontalGoods"].includes(item.type)) {
					item.list = item.list.map(item1 => (item1 as GoodsItem)._id);
				}
			});
			await updateSource<Partial<MiniAppPageRecord>>({
				source: "pageSetting",
				id,
				content: encodeURIComponent(JSON.stringify(copiedContent)),
			});
			await fetchData();
			message.success("已提交");
		} catch (error) {
			console.dir(error);
			toast.error("提交失败");
		} finally {
			setSubmitLoading(false);
		}
	}, [content]);
	useEffect(() => {
		fetchData();
	}, []);
	const initValues = useCallback((currentContent?: ConfigurePageContentItem[]) => swiperEditorRef.current?.initValues(currentContent || content), [content]);
	useEffect(() => {
		if (selectedIndex !== null) {
			initValues();
		}
	}, [selectedIndex]);
	const [operateIndex, setOperateIndex] = useState<number | null>(null);
	const editorList: {
		type: ConfigurePageContentItemType;
		Editor: ForwardRefExoticComponent<RefAttributes<SwiperEditorRef>> | FC;
		ref?: MutableRefObject<SwiperEditorRef | null>;
	}[] = [
		{
			type: "swiper",
			Editor: SwiperEditor,
			ref: swiperEditorRef,
		},
		{
			type: "cat",
			Editor: CatEditor,
		},
		{
			type: "verticalGoods",
			Editor: GoodsEditor,
		},
		{
			type: "horizontalGoods",
			Editor: GoodsEditor,
		},
		{
			type: 'richText',
			Editor: RichTextEditor
		}
	];
	return (
		<ConfigurePageContext.Provider
			value={{
				content,
				setContent,
				setSelectedIndex,
				selectedIndex,
				addTypeOpen,
				setAddTypeOpen,
				operateIndex,
				setOperateIndex,
			}}
		>
			<div>
				<Button icon={<LeftOutlined />} shape="round" className="mb-2" onClick={() => history.replace(MINIAPPPAGE)}>
					返回列表
				</Button>
				<div className="flex">
					<PreviewDevice />
					<StyledEditorArea className="ml-24 px-8 pb-10 grow flex flex-col relative">
						{editorList.map(
							({ type, Editor, ref }, index) =>
								selectedIndex !== null &&
								content[selectedIndex].type === type && (
									<Fragment key={index}>
										<Editor {...(ref ? { ref } : {})} />
									</Fragment>
								)
						)}
						<Button onClick={updateContent} type="primary" disabled={submitLoading} className="px-12 absolute bottom-0">
							提交
						</Button>
					</StyledEditorArea>
				</div>
			</div>
		</ConfigurePageContext.Provider>
	);
};

export default ConfigurePage;
